package com.property.demo.config;

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

/**
 * Sa-Token 配置类
 */
@Configuration
public class SaTokenConfig implements WebMvcConfigurer {
    
    /**
     * 注册 Sa-Token 拦截器，打开注解式鉴权功能
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册 Sa-Token 拦截器，打开注解式鉴权功能
        registry.addInterceptor(new SaInterceptor(handler -> {
            // 指定一些路径需要登录才能访问
            SaRouter.match("/api/**")
                    .notMatch("/api/auth/**", "/api/satoken/login", "/api/satoken/logout")
                    .check(r -> StpUtil.checkLogin());
            
            // 权限认证示例
            SaRouter.match("/api/system/role/**", r -> StpUtil.checkPermission("system:role"));
            SaRouter.match("/api/system/permission/**", r -> StpUtil.checkPermission("system:permission"));
            SaRouter.match("/api/system/user/**", r -> StpUtil.checkPermission("system:user"));
            
            // 小区管理权限
            SaRouter.match("/api/property/community/**", r -> StpUtil.checkPermission("property:community"));
            
            // 房产管理权限
            SaRouter.match("/api/property/building/**", r -> StpUtil.checkPermission("property:building"));
            SaRouter.match("/api/property/home/**", r -> StpUtil.checkPermission("property:home"));
            
            // 车位管理权限
            SaRouter.match("/api/property/parking/**", r -> StpUtil.checkPermission("property:parking"));
            
            // 人员管理权限
            SaRouter.match("/api/property/personnel/**", r -> StpUtil.checkPermission("property:personnel"));
            
            // 服务管理权限
            SaRouter.match("/api/property/service/**", r -> StpUtil.checkPermission("property:service"));
        })).addPathPatterns("/**");
    }
    
    /**
     * Sa-Token 整合 jwt (Simple 简单模式)
     */
    @Bean
    public StpLogic getStpLogicJwt() {
        return new StpLogicJwtForSimple();
    }
    
    /**
     * 全局异常处理
     */
    @RestControllerAdvice
    public static class GlobalExceptionHandler {
        
        /**
         * 处理未登录异常
         */
        @ExceptionHandler(NotLoginException.class)
        @ResponseStatus(HttpStatus.UNAUTHORIZED)
        public Map<String, Object> handleNotLoginException(NotLoginException e) {
            Map<String, Object> result = new HashMap<>();
            result.put("code", 401);
            result.put("message", "未登录或登录已过期");
            result.put("data", null);
            return result;
        }
        
        /**
         * 处理无权限异常
         */
        @ExceptionHandler(NotPermissionException.class)
        @ResponseStatus(HttpStatus.FORBIDDEN)
        public Map<String, Object> handleNotPermissionException(NotPermissionException e) {
            Map<String, Object> result = new HashMap<>();
            result.put("code", 403);
            result.put("message", "无此权限：" + e.getPermission());
            result.put("data", null);
            return result;
        }
        
        /**
         * 处理无角色异常
         */
        @ExceptionHandler(NotRoleException.class)
        @ResponseStatus(HttpStatus.FORBIDDEN)
        public Map<String, Object> handleNotRoleException(NotRoleException e) {
            Map<String, Object> result = new HashMap<>();
            result.put("code", 403);
            result.put("message", "无此角色：" + e.getRole());
            result.put("data", null);
            return result;
        }
    }
} 